package com.the4man.framework.generate;

import com.the4man.framework.jdbc.BeanUtil;
import com.the4man.framework.jdbc.JDBCUtil;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * Created by lenovo on 2017/12/12.
 */
public class JavaGenerateUtil {
    SimpleDateFormat df = new SimpleDateFormat("yyyy-mm-dd");

    public JavaGenerateUtil() {
    }

    private String getClassPath() {
        String projectath = System.getProperty("user.dir");
        String srcpath = projectath + File.separator + "src" + File.separator + "main" + File.separator + "java";
        return srcpath;
    }

    private String getResoucePath() {
        String projectath = System.getProperty("user.dir");
        String srcpath = projectath + File.separator + "src" + File.separator + "main" + File.separator + "resources";
        return srcpath;
    }

    public static void main(String[] args) {
        JavaGenerateUtil j = new JavaGenerateUtil();
        System.out.println(j.getClassPath());
    }

    private void writerFileClassPath(StringBuffer buff, String fileName) {
        String path = this.getClassPath();
        this.writeFile(path, buff, fileName);
    }

    private void writerFileResourcePath(StringBuffer buff, String fileName) {
        String path = this.getResoucePath();
        this.writeFile(path, buff, fileName);
    }

    private void writeFile(String path, StringBuffer buff, String fileName) {
        String filePath = path + fileName;
        File file = new File(filePath);
        if(!file.exists()) {
            file.getParentFile().mkdirs();
        }

        OutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            out = new FileOutputStream(file);
            osw = new OutputStreamWriter(out);
            bw = new BufferedWriter(osw);
            bw.write(buff.toString());
            bw.flush();
        } catch (FileNotFoundException var20) {
            var20.printStackTrace();
        } catch (IOException var21) {
            var21.printStackTrace();
        } finally {
            try {
                if(bw != null) {
                    bw.close();
                }

                if(osw != null) {
                    osw.close();
                }

                if(out != null) {
                    out.close();
                }
            } catch (IOException var19) {
                var19.printStackTrace();
            }

        }

        System.out.println(" 生成" + file.getAbsolutePath() + "完成!");
    }

    public void createModel(String projectName, String className, List<FieldBean> list) {
        StringBuffer buff = new StringBuffer();
        buff.append(this.createPackageString(projectName, "model"));
        buff.append("\n");
        buff.append("\n");
        buff.append("import lombok.Data;");
        buff.append("\n");
        buff.append("import com.the4man.framework.pagemodel.PPage;");
        buff.append("\n");
        buff.append("\n");
        buff.append(this.createNote());
        buff.append("@Data");
        buff.append("\n");
        buff.append("public class " + className + " extends PPage {");
        buff.append("\n");
        if(list != null && list.size() > 0) {
            Iterator var6 = list.iterator();

            while(var6.hasNext()) {
                FieldBean bean = (FieldBean)var6.next();
                buff.append(bean.toString() + "\n");
            }
        }

        buff.append("\n");
        buff.append("\n");
        buff.append("//============分割线 用于展示的字段声明在下面=========================================");
        buff.append("\n");
        String clazzEnd = "}";
        buff.append(clazzEnd);
        this.writerFileClassPath(buff, "/com/the4man/" + projectName + "/model/" + className + ".java");
    }

    public void createDao(String projectName, String modelName) {
        StringBuffer buff = new StringBuffer();
        buff.append(this.createPackageString(projectName, "dao"));
        buff.append("import com.the4man.framework.base.BaseMapper;");
        buff.append("import com.the4man.cnbdw.model." + modelName + ";");
        buff.append("\n");
        buff.append("\n");
        buff.append(this.createNote());
        buff.append("public interface " + modelName + "Mapper extends BaseMapper<" + modelName + "> {");
        buff.append("\n");
        buff.append("\n");
        buff.append("}");
        this.writerFileClassPath(buff, "/com/the4man/" + projectName + "/dao/" + modelName + "Mapper.java");
    }

    private String createPackageString(String projectName, String type) {
        return "package com.the4man." + projectName + "." + type + ";" + "\n" + "\n";
    }

    public void createIService(String projectName, String modelName) {
        StringBuffer buff = new StringBuffer();
        buff.append(this.createPackageString(projectName, "service"));
        buff.append("import com.the4man." + projectName + ".model." + modelName + ";");
        buff.append("import com.the4man.framework.base.IBaseSerivce;");
        buff.append("\n");
        buff.append("\n");
        buff.append("\n");
        buff.append("\n");
        buff.append(this.createNote());
        buff.append("public interface I" + modelName + "Service extends IBaseSerivce<" + modelName + "> {");
        buff.append("}");
        this.writerFileClassPath(buff, "/com/the4man/" + projectName + "/service/I" + modelName + "Service.java");
    }

    public void createService(String projectName, String modelName) {
        StringBuffer buff = new StringBuffer();
        buff.append(this.createPackageString(projectName, "service.impl"));
        buff.append("\n");
        buff.append("import javax.annotation.Resource;");
        buff.append("\n");
        buff.append("import com.the4man." + projectName + ".model." + modelName + ";");
        buff.append("\n");
        buff.append("import org.springframework.stereotype.Service;");
        buff.append("\n");
        buff.append("import com.the4man." + projectName + ".dao." + modelName + "Mapper;");
        buff.append("\n");
        buff.append("import com.the4man." + projectName + ".service.I" + modelName + "Service;");
        buff.append("\n");
        buff.append("import com.the4man.framework.base.BaseService;");
        buff.append("\n");
        buff.append("\n");
        buff.append("\n");
        buff.append(this.createNote());
        buff.append("@Service(\"");
        buff.append(BeanUtil.firstStrToLower(modelName));
        buff.append("Service\")");
        buff.append("\n");
        buff.append("public class " + modelName + "ServiceImpl extends BaseService<" + modelName + "> implements I" + modelName + "Service {");
        buff.append("\n");
        buff.append("    private " + modelName + "Mapper " + this.firtLetterCase(modelName) + "Mapper;");
        buff.append("\n");
        buff.append("    @Resource");
        buff.append("\n");
        buff.append("    public void set" + modelName + "Mapper(" + modelName + "Mapper mapper) {");
        buff.append("\n");
        buff.append("        " + this.firtLetterCase(modelName) + "Mapper = mapper;");
        buff.append("\n");
        buff.append("        super.setBaseMapper(mapper);");
        buff.append("\n");
        buff.append("    }");
        buff.append("\n");
        buff.append("    /*=============================================================================*/");
        buff.append("\n");
        buff.append("}");
        this.writerFileClassPath(buff, "/com/the4man/" + projectName + "/service/impl/" + modelName + "ServiceImpl.java");
    }

    public String createNote() {
        String str = "";
        str = str + "/**\n";
        str = str + " * \n";
        str = str + " * @Description\n";
        str = str + " * @Author:[" + System.getProperty("user.name") + "]\n";
        str = str + " * @Since:[" + this.df.format(new Date()) + "]\n";
        str = str + " * @Version:1.0\n";
        str = str + " *\n";
        str = str + " */";
        str = str + "\n";
        return str;
    }

    public void createConfig(String projectName, String className, String tableName, List<FieldBean> list) {
        StringBuffer buff = new StringBuffer();
        buff.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
        buff.append("\n");
        buff.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\" >");
        buff.append("\n");
        buff.append("<mapper namespace=\"com.the4man." + projectName + ".dao." + className + "Mapper\" >");
        buff.append("\n");
        buff.append("    <sql id=\"Base_Column_List\">");
        buff.append("\n");
        buff.append("        " + this.getBaseColumnList(list));
        buff.append("\n");
        buff.append("    </sql>");
        buff.append("\n");
        buff.append("\n");
        buff.append("    <select id=\"selectForPage\" resultType=\"" + this.getPackageToConfig(projectName, className) + "\" parameterType=\"" + this.getPackageToConfig(projectName, className) + "\">");
        buff.append("\n");
        buff.append("        select ");
        buff.append("\n");
        buff.append("        <include refid=\"Base_Column_List\" />");
        buff.append("\n");
        buff.append("        from " + tableName);
        buff.append("\n");
        buff.append("    </select>");
        buff.append("\n");
        buff.append("\n");
        buff.append("    <select id=\"select\" resultType=\"" + this.getPackageToConfig(projectName, className) + "\" parameterType=\"" + this.getPackageToConfig(projectName, className) + "\">");
        buff.append("\n");
        buff.append("        select ");
        buff.append("\n");
        buff.append("        <include refid=\"Base_Column_List\" />");
        buff.append("\n");
        buff.append("        from " + tableName);
        buff.append("\n");
        buff.append("    </select>");
        buff.append("\n");
        buff.append("\n");
        buff.append("    <select id=\"selectById\" resultType=\"" + this.getPackageToConfig(projectName, className) + "\" parameterType=\"int\">");
        buff.append("\n");
        buff.append("        select ");
        buff.append("\n");
        buff.append("        <include refid=\"Base_Column_List\" />");
        buff.append("\n");
        buff.append("        from " + tableName);
        buff.append("\n");
        buff.append("        where id = #{id}");
        buff.append("\n");
        buff.append("    </select>");
        buff.append("\n");
        buff.append("\n");
        buff.append("    <insert id=\"insert\" parameterType=\"" + this.getPackageToConfig(projectName, className) + "\">");
        buff.append("\n");
        buff.append("        insert into " + tableName);
        buff.append("\n");
        buff.append("            (" + this.getBaseColumnList(list) + ")");
        buff.append("\n");
        buff.append("        values");
        buff.append("\n");
        buff.append("            (" + this.getBaseColumnList_2(list) + ")");
        buff.append("\n");
        buff.append("    </insert>");
        buff.append("\n");
        buff.append("\n");
        buff.append("    <delete id=\"delete\" parameterType=\"java.util.List\">");
        buff.append("\n");
        buff.append("        delete from " + tableName);
        buff.append("\n");
        buff.append("        where id in ");
        buff.append("\n");
        buff.append("        <foreach collection=\"list\"  item=\"ids\"  open=\"(\" separator=\",\" close=\")\">");
        buff.append("\n");
        buff.append("            #{ids}");
        buff.append("\n");
        buff.append("        </foreach>");
        buff.append("\n");
        buff.append("    </delete>");
        buff.append("\n");
        buff.append("\n");
        buff.append("    <update id=\"update\" parameterType=\"" + this.getPackageToConfig(projectName, className) + "\">");
        buff.append("\n");
        buff.append("        update " + tableName + " set ");
        buff.append("\n");
        buff.append(this.getBaseColumnList_3(list));
        buff.append("    </update>");
        buff.append("\n");
        buff.append("\n");
        buff.append("\n");
        buff.append("\n");
        buff.append("    <!-- ===========================分割线===================================================== -->");
        buff.append("\n");
        buff.append("</mapper>");
        this.writerFileResourcePath(buff, "/mapping/mysql/" + className + "Mapper.xml");
    }

    private String getBaseColumnList(List<FieldBean> list) {
        String colums = "";
        if(list != null && list.size() > 0) {
            for(int i = 0; i < list.size(); ++i) {
                colums = colums + ((FieldBean)list.get(i)).getName();
                if(i != list.size() - 1) {
                    colums = colums + ",";
                }
            }
        }

        return colums;
    }

    private String getBaseColumnList_2(List<FieldBean> list) {
        String colums = "";
        if(list != null && list.size() > 0) {
            for(int i = 0; i < list.size(); ++i) {
                colums = colums + "#{" + ((FieldBean)list.get(i)).getName() + "}";
                if(i != list.size() - 1) {
                    colums = colums + ",";
                }
            }
        }

        return colums;
    }

    private String getBaseColumnList_3(List<FieldBean> list) {
        String colums = "";
        if(list != null && list.size() > 0) {
            for(int i = 0; i < list.size(); ++i) {
                String name = ((FieldBean)list.get(i)).getName();
                colums = colums + "        " + name + "=#{" + name + "}";
                if(i != list.size() - 1) {
                    colums = colums + ", \n";
                }
            }

            colums = colums + "\n";
        }

        return colums;
    }

    private String getPackageToConfig(String projectName, String className) {
        return "com.the4man." + projectName + ".model." + className;
    }

    public void create(String dbName, String tableName, String projectName, String className) {
        JDBCUtil jdbcUtil = new JDBCUtil();
        List<FieldBean> list = jdbcUtil.getTableColumnsByTableName(dbName, tableName);
        this.createModel(projectName, className, list);
        this.createDao(projectName, className);
        this.createConfig(projectName, className, tableName, list);
        this.createIService(projectName, className);
        this.createService(projectName, className);
    }

    private String firtLetterCase(String str) {
        return str.replace(str.charAt(0), (char)(str.charAt(0) + 32));
    }
}
